﻿using MengLin.OOP.DesignPattern.FlyWeightPattern.Word;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MengLin.OOP.DesignPattern.Flyweight.Letter
{
    public partial class TestFlyweightPatternForm : Form
    {
        public TestFlyweightPatternForm()
        {
            InitializeComponent();
        }

        private void btnTestFlyweightPattern_Click(object sender, EventArgs eventArgs)
        {
            //说到对象复用，最容易想到的是单例模式
            //单例模式：可以保证进程中只有一个实例，那么就可以到处复用，性能优化
            //要做到单例，需要改造类，增加单例逻辑，破坏单例封装

            //有没有办法，既能对象复用，又不用破坏类的封装？
            //1.统一入口-想控制全局的东西
            //2.添加重用逻辑-静态字典缓存一下

            //MengLin
            #region 传统写法
            {
                //M m = new M();
                //E e = new E();
                //N n = new N();
                //G g = new G();
                //L l = new L();
                //I i = new I();
                //Console.WriteLine($"{m.Get()}{e.Get()}{n.Get()}{g.Get()}{l.Get()}{i.Get()}{n.Get()}被构造");
            }
            #endregion

            #region 享元模式写法
            {
                BaseWord m = FlyweightLetterFactory.CreateWord(WordType.M);
                BaseWord e = FlyweightLetterFactory.CreateWord(WordType.E);
                BaseWord n1 = FlyweightLetterFactory.CreateWord(WordType.N);
                BaseWord g = FlyweightLetterFactory.CreateWord(WordType.G);
                BaseWord l = FlyweightLetterFactory.CreateWord(WordType.L);
                BaseWord i = FlyweightLetterFactory.CreateWord(WordType.I);
                BaseWord n2 = FlyweightLetterFactory.CreateWord(WordType.N);
                Console.WriteLine("{0}{1}{2}{3}{4}{5}{6}", m.Get(), e.Get(), n1.Get(), g.Get(), l.Get(), i.Get(), n2.Get());
            }
            #endregion

            //享元模式：为了解决对象的复用问题，提供第三方的管理，能完成对象的复用
            //1.还可以自行实例化对象，不像单例是强制保证的 
            //2.享元工厂也可以初始化多个对象，其他地方需要使用对象可以找我拿(修改个状态)，用完之后再放回来(状态改回来)，避免重复的创建和销毁对象，尤其对于非托管资源---池化资源管理
            //for (int k = 0; k < 5; k++)
            //{
            //    Task.Run(() =>//启动5个线程完成计算
            //    {
            //        BaseWord m = FlyweightLetterFactory.CreateWord(WordType.M);
            //        BaseWord e = FlyweightLetterFactory.CreateWord(WordType.E);
            //        BaseWord n = FlyweightLetterFactory.CreateWord(WordType.N);
            //        BaseWord g = FlyweightLetterFactory.CreateWord(WordType.G);
            //        BaseWord l = FlyweightLetterFactory.CreateWord(WordType.L);
            //        BaseWord i = FlyweightLetterFactory.CreateWord(WordType.I);
            //        BaseWord n2 = FlyweightLetterFactory.CreateWord(WordType.N);

            //        Console.WriteLine($"{m.Get()}{e.Get()}{n.Get()}{g.Get()}{l.Get()}{i.Get()}{n2.Get()}被构造");
            //    });
            //}

            #region 其他方法重用对象
            {
                TestMethod1();

                TestMethod2();

                OtherClass.Show();//其他类重用对象
            }
            #endregion

            Console.Read();
        }

        /// <summary>
        /// 一个方法，使对象重用
        /// </summary>
        private void TestMethod1()
        {
            #region 重复使用
            //M m = new M();
            //E e = new E();
            //N n = new N();
            //G g = new G();
            //L l = new L();
            //I i = new I();
            //Console.WriteLine($"{m.Get()}{e.Get()}{n.Get()}{g.Get()}{l.Get()}{i.Get()}{n.Get()}被构造");
            #endregion

            BaseWord m = FlyweightLetterFactory.CreateWord(WordType.M);
            BaseWord e = FlyweightLetterFactory.CreateWord(WordType.E);
            BaseWord n = FlyweightLetterFactory.CreateWord(WordType.N);
            BaseWord g = FlyweightLetterFactory.CreateWord(WordType.G);
            BaseWord l = FlyweightLetterFactory.CreateWord(WordType.L);
            BaseWord i = FlyweightLetterFactory.CreateWord(WordType.I);
            BaseWord n2 = FlyweightLetterFactory.CreateWord(WordType.N);

            Console.WriteLine($"{m.Get()}{e.Get()}{n.Get()}{g.Get()}{l.Get()}{i.Get()}{n.Get()}被构造");
        }

        /// <summary>
        /// 另一个方法，使对象重用
        /// </summary>
        private void TestMethod2()
        {
            #region 重复使用
            //M m = new M();
            //E e = new E();
            //N n = new N();
            //G g = new G();
            //L l = new L();
            //I i = new I();
            //Console.WriteLine($"{m.Get()}{e.Get()}{n.Get()}{g.Get()}{l.Get()}{i.Get()}{n.Get()}被构造");
            #endregion

            BaseWord m = FlyweightLetterFactory.CreateWord(WordType.M);
            BaseWord e = FlyweightLetterFactory.CreateWord(WordType.E);
            BaseWord n = FlyweightLetterFactory.CreateWord(WordType.N);
            BaseWord g = FlyweightLetterFactory.CreateWord(WordType.G);
            BaseWord l = FlyweightLetterFactory.CreateWord(WordType.L);
            BaseWord i = FlyweightLetterFactory.CreateWord(WordType.I);
            BaseWord n2 = FlyweightLetterFactory.CreateWord(WordType.N);

            Console.WriteLine($"{m.Get()}{e.Get()}{n.Get()}{g.Get()}{l.Get()}{i.Get()}{n.Get()}被构造");
        }
    }
}
